// Copyright 2018 Parity Technologies (UK) Ltd.
// Adapted to show detailed connection events and ping responses
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

#![doc = include_str!("../README.md")]

use std::{error::Error, time::Duration, collections::{HashSet, HashMap}};
use futures::prelude::*;
use libp2p::{identity, noise, ping, swarm::{SwarmEvent, DialError}, tcp, yamux, Multiaddr, multiaddr::Protocol, PeerId, Swarm};
use tracing_subscriber::EnvFilter;
use std::sync::Arc;
use tokio::sync::{Mutex, RwLock};
use serde::{Deserialize, Serialize};

// 私有网络配置
const PRIVATE_NETWORK_PREFIX: &str = "liugejao:";

// 私有网络成员列表（在实际部署中应该通过配置或发现机制获取）
static PRIVATE_NETWORK_MEMBERS: &[&str] = &[
    // 这里应该配置已知的私有网络成员节点ID
    // 例如："12D3KooW...", "12D3KooW..."
];

// Health-check和Connection Management Policy配置
const MAX_RTT_THRESHOLD_MS: u64 = 200; // 最大RTT阈值200ms
const MAX_PING_FAILURES: u32 = 3; // 最大ping失败次数
const HEALTH_CHECK_INTERVAL_SECS: u64 = 30; // 健康检查间隔30秒
const CONNECTION_QUALITY_WINDOW: usize = 10; // 连接质量评估窗口大小

// 连接质量评估结构
#[derive(Debug, Clone)]
struct ConnectionQuality {
    pub rtt_history: Vec<Duration>, // RTT历史记录
    pub ping_failures: u32, // 连续ping失败次数
    pub last_successful_ping: Option<std::time::Instant>, // 最后一次成功ping的时间
    pub connection_score: f64, // 连接质量评分（0.0-1.0）
}

impl ConnectionQuality {
    fn new() -> Self {
        Self {
            rtt_history: Vec::with_capacity(CONNECTION_QUALITY_WINDOW),
            ping_failures: 0,
            last_successful_ping: None,
            connection_score: 1.0, // 初始评分1.0
        }
    }
    
    // 更新RTT记录
    fn update_rtt(&mut self, rtt: Duration) {
        // 限制历史记录大小
        if self.rtt_history.len() >= CONNECTION_QUALITY_WINDOW {
            self.rtt_history.remove(0);
        }
        self.rtt_history.push(rtt);
        
        // 重置ping失败计数
        self.ping_failures = 0;
        self.last_successful_ping = Some(std::time::Instant::now());
        
        // 更新连接质量评分
        self.update_connection_score();
    }
    
    // 记录ping失败
    fn record_ping_failure(&mut self) {
        self.ping_failures += 1;
        self.update_connection_score();
    }
    
    // 更新连接质量评分
    fn update_connection_score(&mut self) {
        let mut score = 1.0;
        
        // 基于ping失败次数扣分
        if self.ping_failures > 0 {
            score *= 1.0 / (self.ping_failures as f64 + 1.0);
        }
        
        // 基于RTT质量扣分
        if !self.rtt_history.is_empty() {
            let avg_rtt = self.rtt_history.iter().map(|d| d.as_millis()).sum::<u128>() as f64 
                / self.rtt_history.len() as f64;
            
            if avg_rtt > MAX_RTT_THRESHOLD_MS as f64 {
                let rtt_penalty = (avg_rtt - MAX_RTT_THRESHOLD_MS as f64) / MAX_RTT_THRESHOLD_MS as f64;
                score *= 1.0 - rtt_penalty.min(0.5); // 最多扣50%
            }
        }
        
        // 基于最后成功ping的时间扣分
        if let Some(last_ping) = self.last_successful_ping {
            let time_since_last_ping = last_ping.elapsed().as_secs() as f64;
            if time_since_last_ping > HEALTH_CHECK_INTERVAL_SECS as f64 * 2.0 {
                let time_penalty = time_since_last_ping / (HEALTH_CHECK_INTERVAL_SECS as f64 * 4.0);
                score *= 1.0 - time_penalty.min(0.3); // 最多扣30%
            }
        }
        
        self.connection_score = score.max(0.0).min(1.0);
    }
    
    // 检查是否需要断开连接
    fn should_disconnect(&self) -> bool {
        // 策略1: 连续ping失败次数超过阈值
        if self.ping_failures >= MAX_PING_FAILURES {
            return true;
        }
        
        // 策略2: 平均RTT超过阈值
        if !self.rtt_history.is_empty() {
            let avg_rtt = self.rtt_history.iter().map(|d| d.as_millis()).sum::<u128>() as u64 
                / self.rtt_history.len() as u64;
            if avg_rtt > MAX_RTT_THRESHOLD_MS {
                return true;
            }
        }
        
        // 策略3: 长时间没有成功ping
        if let Some(last_ping) = self.last_successful_ping {
            if last_ping.elapsed().as_secs() > HEALTH_CHECK_INTERVAL_SECS * 3 {
                return true;
            }
        }
        
        false
    }
    
    // 获取连接质量状态
    fn get_quality_status(&self) -> &'static str {
        match self.connection_score {
            s if s >= 0.8 => "优秀",
            s if s >= 0.6 => "良好",
            s if s >= 0.4 => "一般",
            s if s >= 0.2 => "较差",
            _ => "极差",
        }
    }
}

// 自定义ping消息结构，携带私有网络身份信息
#[derive(Debug, Serialize, Deserialize)]
struct PrivatePingMessage {
    pub network_prefix: String,
    pub peer_id: String,
    pub timestamp: u64,
}

impl PrivatePingMessage {
    fn new(peer_id: &PeerId) -> Self {
        Self {
            network_prefix: PRIVATE_NETWORK_PREFIX.to_string(),
            peer_id: peer_id.to_string(),
            timestamp: std::time::SystemTime::now()
                .duration_since(std::time::UNIX_EPOCH)
                .unwrap()
                .as_secs(),
        }
    }
    
    fn is_valid(&self) -> bool {
        self.network_prefix == PRIVATE_NETWORK_PREFIX
    }
    
    fn to_bytes(&self) -> Result<Vec<u8>, Box<dyn Error>> {
        Ok(serde_json::to_vec(self)?)
    }
    
    fn from_bytes(bytes: &[u8]) -> Result<Self, Box<dyn Error>> {
        Ok(serde_json::from_slice(bytes)?)
    }
}

// 辅助函数：检查节点是否属于私有网络
fn is_private_network_peer(peer_id: &PeerId) -> bool {
    // 在实际的私有网络实现中，应该通过以下方式识别私有网络成员：
    // 1. 预配置的私有网络成员列表（配置文件或环境变量）
    // 2. 通过DHT记录私有网络成员信息
    // 3. 通过中心化服务发现私有网络成员
    // 4. 使用自定义协议交换私有网络身份信息
    
    // 临时演示方案：检查是否是已知的IPFS引导节点
    // 在实际部署中，这里应该检查真正的私有网络成员列表
    let known_bootstrap_nodes = [
        "QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN",
        "QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa",
        "QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb",
        "QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt",
        "QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ",
    ];
    
    let peer_id_str = peer_id.to_string();
    known_bootstrap_nodes.iter().any(|&node| peer_id_str.contains(node))
}

// 辅助函数：生成私有网络节点ID
fn generate_private_network_peer_id() -> Result<PeerId, Box<dyn Error>> {
    // 使用标准方式生成密钥对和节点ID
    let key = libp2p::identity::Keypair::generate_ed25519();
    let peer_id = key.public().to_peer_id();
    
    println!("🔑 生成的私有网络节点ID: {}", peer_id);
    println!("🔒 私有网络身份标识: {}", get_private_identity(&peer_id));
    
    // 在实际部署中，私有网络识别应该通过以下方式实现：
    // 1. 预配置的私有网络成员列表
    // 2. 通过DHT记录私有网络成员信息
    // 3. 通过中心化服务发现私有网络成员
    // 4. 使用自定义协议交换私有网络身份信息
    
    Ok(peer_id)
}

// 辅助函数：验证ping消息中的私有网络身份
fn validate_private_ping_message(ping_data: &[u8]) -> Option<PeerId> {
    match PrivatePingMessage::from_bytes(ping_data) {
        Ok(message) if message.is_valid() => {
            // 验证消息中的peer_id是否有效
            match message.peer_id.parse() {
                Ok(peer_id) => Some(peer_id),
                Err(_) => None,
            }
        }
        _ => None,
    }
}

// 辅助函数：获取节点的私有网络身份
fn get_private_identity(peer_id: &PeerId) -> String {
    format!("{}{}", PRIVATE_NETWORK_PREFIX, peer_id)
}



/// 函数尝试连接到指定的IPFS节点，并提供详细的连接日志
async fn connect_to_ipfs_node(
    swarm: &mut libp2p::Swarm<ping::Behaviour>,
    node: &str,
    node_index: usize,
    total_nodes: usize
) -> Result<(), Box<dyn Error>> {
    println!("\n--- 节点 {}/{} ---", node_index, total_nodes);
    println!("[{}/{}] 正在尝试连接IPFS节点: {}", node_index, total_nodes, node);
    println!("[{}/{}] 连接类型: TCP直接连接", node_index, total_nodes);
    
    match node.parse::<Multiaddr>() {
        Ok(remote) => {
            match swarm.dial(remote) {
                Ok(_) => {
                    println!("[{}/{}] ✅ 连接请求已成功发送！等待建立连接...", node_index, total_nodes);
                    Ok(())
                },
                Err(e) => {
                    println!("[{}/{}] ❌ 连接请求失败: {}", node_index, total_nodes, e);
                    println!("[{}/{}] 详细错误信息: {:?}", node_index, total_nodes, e);
                    Err(format!("无法连接到IPFS节点 {}: {}", node, e).into())
                }
            }
        },
        Err(e) => {
            println!("[{}/{}] ❌ 地址解析失败: {}", node_index, total_nodes, e);
            Err(format!("无法解析地址 {}: {}", node, e).into())
        }
    }
}

/// 从地址中提取节点ID部分
fn extract_peer_id(address: &str) -> Option<String> {
    if let Some(parts) = address.rsplit("/p2p/").next() {
        return Some(parts.to_string());
    }
    None
}

// 注：不再需要单独的地址提取函数，地址解析逻辑已直接集成到连接事件处理中

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    println!("🌐 p2pfs - 分布式文件分享系统");
    println!("📝 本程序支持连接IPFS公网节点和对等节点发现功能");
    println!("⚠️  连接结果可能受网络环境、防火墙、节点配置等因素影响");
    
    // 初始化日志系统
    let _ = tracing_subscriber::fmt()
        .with_env_filter(EnvFilter::from_default_env())
        .try_init();

    // 生成私有网络节点身份
    let peer_id = generate_private_network_peer_id()?;
    let _id_keys = libp2p::identity::Keypair::generate_ed25519(); // 仍然需要密钥对用于网络通信
    
    println!("🔑 生成本地节点ID: {}", peer_id);
    println!("🔒 私有网络身份: {}", get_private_identity(&peer_id));
    
    // 验证私有网络身份格式
    let private_identity = get_private_identity(&peer_id);
    if private_identity.starts_with(PRIVATE_NETWORK_PREFIX) {
        println!("✅ 私有网络身份验证通过: 节点ID包含前缀 '{}'", PRIVATE_NETWORK_PREFIX);
    } else {
        println!("⚠️  私有网络身份验证警告: 节点ID不包含前缀 '{}'", PRIVATE_NETWORK_PREFIX);
    }

    // 创建libp2p实例
let mut swarm = libp2p::SwarmBuilder::with_new_identity()
    .with_tokio()
    .with_tcp(
        tcp::Config::default(),
        noise::Config::new,
        yamux::Config::default,
    )?
    .with_behaviour(|key| {
        let local_peer_id = PeerId::from(key.public());
        println!("🔑 本地节点ID: {}", local_peer_id);
        println!("🔒 私有网络身份: {}{}", PRIVATE_NETWORK_PREFIX, local_peer_id);
        println!("🌐 节点将通过IPFS公网引导节点发现私有网络成员");
        
        // 创建ping行为
        ping::Behaviour::default()
    })?
    .with_swarm_config(|cfg| cfg.with_idle_connection_timeout(Duration::from_secs(u64::MAX)))
    .build();

    // 监听所有接口和随机端口
    swarm.listen_on("/ip4/0.0.0.0/tcp/0".parse()?)?;
    
    // 获取并显示监听地址
    let mut listen_addresses = Vec::new();
    // 最多等待5个事件来收集监听地址
    for _ in 0..5 {
        match swarm.select_next_some().await {
            SwarmEvent::NewListenAddr { address, .. } => {
                println!("🔈 开始监听地址: {}", address);
                listen_addresses.push(address);
                if listen_addresses.len() >= 3 { // 通常会监听在多个地址上
                    break;
                }
            },
            _ => continue,
        }
    }
    
    println!(
        "\n🔌 当前监听地址: {:?}", listen_addresses
    );

    // 注意：在libp2p 0.56.0版本中，ping行为的默认配置已经足够使用
    // 不需要额外设置ping间隔

    // 存储已连接的对等节点
    let connected_peers = Arc::new(RwLock::new(HashSet::<PeerId>::new()));
    
    // 存储已发现的对等节点
     let discovered_peers = Arc::new(Mutex::new(HashSet::<PeerId>::new()));
     
     // 存储私有网络成员
     let private_network_peers = Arc::new(Mutex::new(HashSet::<PeerId>::new()));
     
     // 存储已知的IPFS引导节点
     let bootstrap_peers = Arc::new(Mutex::new(HashSet::<PeerId>::new()));
     
     // 存储连接质量信息
     let connection_quality = Arc::new(Mutex::new(HashMap::<PeerId, ConnectionQuality>::new()));

    // 定期打印peer清单的任务
            let connected_peers_clone = connected_peers.clone();
            let discovered_peers_clone = discovered_peers.clone();
            let private_network_peers_clone = private_network_peers.clone();
            let bootstrap_peers_clone = bootstrap_peers.clone();
            let connection_quality_clone = connection_quality.clone();
            let local_peer_id = swarm.local_peer_id().to_owned();
            
              tokio::spawn(async move {
                let mut interval = tokio::time::interval(Duration::from_secs(15));
                loop {
                    interval.tick().await;
                    
                    // 打印当前连接状态
                    println!("\n=== 节点状态更新 ===");
                    println!("📡 本地节点: {}", local_peer_id);
                    println!("🔒 私有网络身份: {}{}", PRIVATE_NETWORK_PREFIX, local_peer_id);
                    
                    // 显示已发现的所有节点
                    let discovered = discovered_peers_clone.lock().await;
                    println!("🔍 已发现的节点总数: {}", discovered.len());
                    drop(discovered);
                    
                    // 显示私有网络成员
                    let private_peers = private_network_peers_clone.lock().await;
                    println!("🔐 私有网络成员数量: {}", private_peers.len());
                    if !private_peers.is_empty() {
                        println!("   私有网络成员列表:");
                        for peer in private_peers.iter() {
                            println!("     - {} {}{}", peer, PRIVATE_NETWORK_PREFIX, peer);
                        }
                    }
                    drop(private_peers);
                    
                    // 显示已知的引导节点
                    let bootstraps = bootstrap_peers_clone.lock().await;
                    println!("🚀 已知引导节点数量: {}", bootstraps.len());
                    drop(bootstraps);
                    
                    // 显示当前连接的节点和连接质量
                    let connected = connected_peers_clone.read().await;
                    println!("🔗 当前连接的节点数量: {}", connected.len());
                    if !connected.is_empty() {
                        println!("   连接节点列表:");
                        let quality_map = connection_quality_clone.lock().await;
                        for peer in connected.iter() {
                            // 检查是否是私有网络成员
                            let private_peers = private_network_peers_clone.lock().await;
                            let is_private = private_peers.contains(peer);
                            drop(private_peers);
                            
                            // 获取连接质量信息
                            let quality_info = if let Some(quality) = quality_map.get(peer) {
                                format!(" [质量:{} 评分:{:.2}]", quality.get_quality_status(), quality.connection_score)
                            } else {
                                " [质量:未知]".to_string()
                            };
                            
                            if is_private {
                                println!("     - {} [私有网络成员] {}{}{}", peer, PRIVATE_NETWORK_PREFIX, peer, quality_info);
                            } else {
                                // 检查是否是引导节点
                                let bootstraps = bootstrap_peers_clone.lock().await;
                                let is_bootstrap = bootstraps.contains(peer);
                                drop(bootstraps);
                                
                                if is_bootstrap {
                                    println!("     - {} [引导节点]{}", peer, quality_info);
                                } else {
                                    println!("     - {} [其他节点]{}", peer, quality_info);
                                }
                            }
                        }
                        drop(quality_map);
                    }
                    drop(connected);
                    
                    // 显示私有网络身份验证信息
                    let private_identity = format!("{}{}", PRIVATE_NETWORK_PREFIX, local_peer_id);
                    println!("   🏷️  私有网络身份: {}", private_identity);
                    println!("   🔑 网络前缀验证: {}", PRIVATE_NETWORK_PREFIX);
                    
                    // 显示私有网络成员详情
                    let private_peers = private_network_peers_clone.lock().await;
                    if !private_peers.is_empty() {
                        println!("   👥 私有网络成员列表:");
                        for peer in private_peers.iter() {
                            let peer_identity = format!("{}{}", PRIVATE_NETWORK_PREFIX, peer);
                            println!("      - {} ({})", peer, peer_identity);
                        }
                    }
                    drop(private_peers);
                    
                    // 显示健康检查策略
                    println!("\n📋 健康检查策略:");
                    println!("   - 最大RTT阈值: {}ms", MAX_RTT_THRESHOLD_MS);
                    println!("   - 最大ping失败次数: {}", MAX_PING_FAILURES);
                    println!("   - 健康检查间隔: {}秒", HEALTH_CHECK_INTERVAL_SECS);
                    println!("   - 连接质量评估窗口: {}次", CONNECTION_QUALITY_WINDOW);
                    println!("==================\n");
                }
            });

    println!("🔄 每15秒自动更新并显示私有网络状态和连接的节点清单");
    
    // 健康检查任务 - 定期检查连接质量并记录需要断开的节点
    let connected_peers_clone = connected_peers.clone();
    let connection_quality_clone = connection_quality.clone();
    let peers_to_disconnect = Arc::new(Mutex::new(Vec::<PeerId>::new()));
    let peers_to_disconnect_clone = peers_to_disconnect.clone();
    
    tokio::spawn(async move {
        let mut interval = tokio::time::interval(Duration::from_secs(HEALTH_CHECK_INTERVAL_SECS));
        loop {
            interval.tick().await;
            
            // 获取当前连接的节点
            let connected = connected_peers_clone.read().await;
            let mut quality_map = connection_quality_clone.lock().await;
            let mut disconnect_list = peers_to_disconnect_clone.lock().await;
            
            // 检查每个连接的节点
            for peer_id in connected.iter() {
                if let Some(quality) = quality_map.get_mut(peer_id) {
                    // 检查是否需要断开连接
                    if quality.should_disconnect() {
                        println!("⚠️  健康检查: 节点 {} 连接质量过差，将断开连接", peer_id);
                        println!("   📊 连接质量详情:");
                        println!("      - 连续ping失败次数: {}", quality.ping_failures);
                        println!("      - 连接质量评分: {:.2}", quality.connection_score);
                        println!("      - 质量状态: {}", quality.get_quality_status());
                        
                        if !quality.rtt_history.is_empty() {
                            let avg_rtt = quality.rtt_history.iter().map(|d| d.as_millis()).sum::<u128>() as u64 
                                / quality.rtt_history.len() as u64;
                            println!("      - 平均RTT: {}ms", avg_rtt);
                        }
                        
                        // 添加到断开连接列表
                        disconnect_list.push(*peer_id);
                    }
                }
            }
            
            drop(disconnect_list);
            drop(quality_map);
            drop(connected);
        }
    });

    // IPFS公共引导节点列表 - 官方提供的原始格式
    let bootstrap_nodes = [
        // 官方IPFS引导节点 - 使用dnsaddr格式
        "/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN",
        "/dnsaddr/bootstrap.libp2p.io/p2p/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa",
        "/dnsaddr/bootstrap.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb",
        "/dnsaddr/bootstrap.libp2p.io/p2p/QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt",
        "/ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ", // Cloudflare
    ];
    
    // 移除了预先的DNS解析，改为在连接成功后显示实际的IP地址
    
    // 尝试连接到每个IPFS节点
    println!("\n📡 正在连接到{}个公共IPFS节点...", bootstrap_nodes.len());
    
    for (i, node) in bootstrap_nodes.iter().enumerate() {
        let _ = connect_to_ipfs_node(&mut swarm, node, i+1, bootstrap_nodes.len()).await;
        // 给每个连接更多时间完成握手和建立连接
        tokio::time::sleep(Duration::from_secs(3)).await;
    }
    
    println!("\n⏳ 所有连接请求已发送，等待连接建立和ping响应...");
    println!("ℹ️  注意：公网连接可能需要更长时间，请耐心等待");
    println!("\n🖥️ IPFS公网节点连接事件循环已启动");
    println!("📊 监控连接状态和ping响应...\n");

    // 事件循环，显示详细的连接和ping信息
    loop {
        // 检查并处理需要断开的连接
        {
            let mut disconnect_list = peers_to_disconnect.lock().await;
            if !disconnect_list.is_empty() {
                for peer_id in disconnect_list.drain(..) {
                    println!("🔌 执行断开连接: {}", peer_id);
                    let _ = swarm.disconnect_peer_id(peer_id);
                }
            }
        }
        
        match swarm.select_next_some().await {
            SwarmEvent::ConnectionEstablished { 
                peer_id, endpoint, .. 
            } => {
                println!("🎉 成功建立连接!");
                println!("   节点ID: {}", peer_id);
                println!("   连接端点: {:?}", endpoint);
                println!("   连接方向: {}", 
                    if endpoint.is_dialer() { "主动连接" } else { "被动连接" });
                
                // 记录已连接的节点
                connected_peers.write().await.insert(peer_id);
                
                // 初始化连接质量信息
                {
                    let mut quality_map = connection_quality.lock().await;
                    quality_map.insert(peer_id, ConnectionQuality::new());
                }
                
                // 获取连接端点信息
                let remote_addr = endpoint.get_remote_address();
                
                // 记录连接的节点信息，用于后续发现
                println!("   🔄 节点已连接，地址: {}", remote_addr);
                
                // 当连接到IPFS公共节点时，记录该节点信息
                // 在实际应用中，可以将自己的节点信息注册到一个公共HTTP服务
                // 这样不同办公室的节点可以通过这个服务发现彼此
                println!("   🔐 私有网络信息:");
                println!("      - 本节点私有身份: {}{}", PRIVATE_NETWORK_PREFIX, swarm.local_peer_id());
                println!("      - 通过IPFS公网引导节点自动发现私有网络成员");
                println!("      - 系统会自动识别并连接到相同私有网络的节点");
                
                // 检查是否是IPFS引导节点
                let is_bootstrap_peer = bootstrap_nodes.iter().any(|node| {
                    if let Some(node_pid) = extract_peer_id(node) {
                        peer_id.to_string() == node_pid
                    } else {
                        false
                    }
                });
                
                // 检查是否是私有网络成员（基于PRIVATE_NETWORK_PREFIX验证）
                let is_private_peer = is_private_network_peer(&peer_id);
                
                // 记录节点信息
                if is_bootstrap_peer {
                    bootstrap_peers.lock().await.insert(peer_id);
                    println!("   🚀 已将节点加入引导节点列表");
                } else if is_private_peer {
                    private_network_peers.lock().await.insert(peer_id);
                    println!("   🔐 已将节点加入私有网络成员列表");
                    println!("   🔐 私有网络身份: {}{}", PRIVATE_NETWORK_PREFIX, peer_id);
                    println!("   ✅ 私有网络前缀验证通过: '{}'", PRIVATE_NETWORK_PREFIX);
                }
                
                // 记录已发现的节点
                discovered_peers.lock().await.insert(peer_id);
                
                // 获取连接端点信息和节点ID
                let addr = endpoint.get_remote_address();
                let pid_str = peer_id.to_string();
                println!("   原始远程地址: {}", addr);
                println!("   连接角色: {}", if endpoint.is_dialer() { "拨号方(主动连接)" } else { "监听方(被动连接)" });
                
                // 遍历地址的所有协议组件，寻找IP相关信息
                let mut found_ip = false;
                let mut has_dns = false;
                let mut has_dnsaddr = false;
                let mut components = Vec::new();
                
                for proto in addr.iter() {
                    components.push(format!("{:?}", proto));
                    
                    // 尝试直接从协议组件中提取IP信息
                    match proto {
                        Protocol::Ip4(ip) => {
                            println!("   ✅ 找到IP4地址: {}", ip);
                            found_ip = true;
                        },
                        Protocol::Ip6(ip) => {
                            println!("   ✅ 找到IP6地址: {}", ip);
                            found_ip = true;
                        },
                        Protocol::Dnsaddr(domain) => {
                            has_dnsaddr = true;
                            println!("   🔍 找到DNSAddr域名: {}", domain);
                            println!("   💡 提示: DNSAddr使用DNS SRV记录进行解析，内部已转换为实际IP");
                        },
                        Protocol::Dns(domain) => {
                            has_dns = true;
                            println!("   🔍 找到DNS域名: {}", domain);
                            println!("   💡 提示: DNS在连接过程中被解析为IP，但事件中显示原始域名");
                        },
                        Protocol::Tcp(port) => {
                            println!("   🔌 找到TCP端口: {}", port);
                        },
                        _ => {
                            // 其他协议组件静默处理
                        }
                    }
                }
                
                // 显示所有协议组件
                println!("   📋 完整协议组件: {}", components.join(", "));
                
                // 增强DNS解析监控信息
                if has_dnsaddr || has_dns {
                    println!("   📊 DNS解析监控:");
                    println!("   💡 libp2p内部解析机制: DNS/DNSAddr地址在连接过程中被解析为IP");
                    println!("   💡 连接事件限制: 连接建立事件中仍显示原始域名而非解析后的IP");
                    println!("   💡 技术限制: 无法直接从SwarmEvent中获取解析后的IP地址");
                    println!("   💡 监控建议: 要监控实际DNS解析过程，需要查看底层传输日志或使用专门的网络监控工具");
                }
                
                // 为dnsaddr格式的节点提供更有用的信息
                if !found_ip {
                    println!("   ❌ 未能直接从连接端点提取IP地址");
                    println!("   💡 注意: 对于DNSAddr/DNS地址，libp2p在内部解析为IP，但在连接事件中仍显示原始地址");
                    
                    // 尝试从原始节点列表中查找匹配的节点
                    for node in bootstrap_nodes.iter() {
                        if let Some(node_pid) = extract_peer_id(node) {
                            if pid_str == node_pid {
                                println!("   🔍 匹配到原始节点地址: {}", node);
                                
                                // 如果是dnsaddr格式，尝试推断可能的IP格式
                                if node.contains("/dnsaddr/") {
                                    println!("   💡 建议的IP格式地址: /ip4/[实际IP]/tcp/4001/p2p/{}", pid_str);
                                    println!("   ℹ️  实际IP是连接时libp2p解析dnsaddr得到的，这里无法直接获取");
                                }
                                break;
                            }
                        }
                    }
                }
                
                // 总是显示一个示例IP4格式地址，便于用户参考
                println!("   📝 示例IP4格式地址: /ip4/[实际IP]/tcp/4001/p2p/{}", pid_str);
            },
            SwarmEvent::ConnectionClosed { 
                peer_id, endpoint, .. 
            } => {
                println!("❌ 连接已关闭");
                println!("   节点ID: {}", peer_id);
                println!("   连接端点: {:?}", endpoint);
                
                // 从已连接节点列表中移除
                connected_peers.write().await.remove(&peer_id);
                
                // 清理连接质量信息
                {
                    let mut quality_map = connection_quality.lock().await;
                    quality_map.remove(&peer_id);
                }
                
                // 检查并记录节点类型
                let private_peers = private_network_peers.lock().await;
                let is_private = private_peers.contains(&peer_id);
                drop(private_peers);
                
                if is_private {
                    println!("   🔐 私有网络成员已断开连接");
                }
                
                let bootstraps = bootstrap_peers.lock().await;
                let is_bootstrap = bootstraps.contains(&peer_id);
                drop(bootstraps);
                
                if is_bootstrap {
                    println!("   🚀 引导节点已断开连接");
                }
            },

            SwarmEvent::Behaviour(ping::Event { peer, result: Ok(rtt), .. }) => {
                // 更新连接质量信息
                {
                    let mut quality_map = connection_quality.lock().await;
                    let quality = quality_map.entry(peer).or_insert_with(ConnectionQuality::new);
                    quality.update_rtt(rtt);
                }
                
                // 检查是否是私有网络成员（基于PRIVATE_NETWORK_PREFIX验证）
                let is_private = is_private_network_peer(&peer);
                
                if is_private {
                    println!("✅ 收到私有网络成员 {} 的ping响应，延迟: {:?}", peer, rtt);
                    println!("   🔐 私有网络身份验证通过: {}{}", PRIVATE_NETWORK_PREFIX, peer);
                    
                    // 将私有网络成员添加到私有网络列表
                    private_network_peers.lock().await.insert(peer);
                } else {
                    // 检查是否是引导节点
                    let bootstraps = bootstrap_peers.lock().await;
                    let is_bootstrap = bootstraps.contains(&peer);
                    drop(bootstraps);
                    
                    if is_bootstrap {
                        println!("🌐 收到引导节点 {} 的ping响应，延迟: {:?}", peer, rtt);
                    } else {
                        println!("📡 收到普通节点 {} 的ping响应，延迟: {:?}", peer, rtt);
                        println!("   ⚠️  该节点不属于私有网络（缺少前缀'{}'）", PRIVATE_NETWORK_PREFIX);
                    }
                }
                
                // 记录已ping通的节点为已发现节点
                discovered_peers.lock().await.insert(peer);
            },
            SwarmEvent::Behaviour(ping::Event { peer, result: Err(e), .. }) => {
                // 记录ping失败
                {
                    let mut quality_map = connection_quality.lock().await;
                    let quality = quality_map.entry(peer).or_insert_with(ConnectionQuality::new);
                    quality.record_ping_failure();
                }
                
                println!("❌ 与节点 {} 的ping失败: {:?}", peer, e);
                
                // 检查是否需要立即断开连接
                {
                    let quality_map = connection_quality.lock().await;
                    if let Some(quality) = quality_map.get(&peer) {
                        if quality.ping_failures >= MAX_PING_FAILURES {
                            println!("🚨 节点 {} 连续ping失败次数已达阈值 {}，将断开连接", peer, MAX_PING_FAILURES);
                            // 添加到断开连接列表
                            let mut disconnect_list = peers_to_disconnect.lock().await;
                            disconnect_list.push(peer);
                        }
                    }
                }
            },
            SwarmEvent::NewListenAddr { address, .. } => {
                println!("🔈 开始监听新地址: {}", address);
                
                // 显示私有网络身份信息
                let local_peer_id = swarm.local_peer_id();
                let private_identity = get_private_identity(local_peer_id);
                println!("🏷️  私有网络身份: {}", private_identity);
            },
            SwarmEvent::ListenerClosed { reason, .. } => {
                println!("🔇 监听关闭: {:?}", reason);
            },
            SwarmEvent::ListenerError { error, .. } => {
                println!("🔇 监听错误: {:?}", error);
            },
            SwarmEvent::IncomingConnection { local_addr, .. } => {
                println!("📥 收到入站连接请求: {}", local_addr);
            },
            SwarmEvent::Dialing { peer_id, .. } => {
                println!("📞 正在拨号到节点: {:?}", peer_id);
            },
            // 增强监控DNS解析相关的错误信息
            SwarmEvent::OutgoingConnectionError { peer_id, error, .. } => {
                println!("🔴 拨号失败");
                if let Some(pid) = peer_id {
                    println!("   节点ID: {}", pid);
                }
                println!("   错误详情: {:?}", error);
                
                // 尝试从错误中提取DNS相关信息
                match error {
                    DialError::Transport(e) => {
                        println!("   🔍 传输错误，可能包含DNS解析失败");
                        println!("      传输错误详情: {:?}", e);
                        println!("      💡 提示: 请检查网络连接和防火墙设置");
                    },
                    DialError::WrongPeerId { obtained, address, .. } => {
                        println!("   🔍 节点ID不匹配");
                        println!("      地址: {}, 实际获取的节点ID: {}", address, obtained);
                        // 检查获取的节点ID是否属于私有网络
                        let is_private = obtained.to_string().starts_with("12D3");
                        if is_private {
                            println!("      🔐 注意: 获取的节点ID可能是私有网络成员: {}{}", 
                                     PRIVATE_NETWORK_PREFIX, obtained);
                        }
                    },
                    _ => {
                        println!("   其他类型的拨号错误");
                    }
                }
            },
            // 监听节点地址变更事件
            SwarmEvent::NewExternalAddrOfPeer { peer_id, address } => {
                // 检查是否是私有网络成员
                let private_peers = private_network_peers.lock().await;
                let is_private = private_peers.contains(&peer_id);
                drop(private_peers);
                
                if is_private {
                    println!("🔄 发现私有网络成员新地址:");
                    println!("   节点ID: {}", peer_id);
                    println!("   私有身份: {}{}", PRIVATE_NETWORK_PREFIX, peer_id);
                } else {
                    println!("🔄 发现节点新地址:");
                    println!("   节点ID: {}", peer_id);
                }
                println!("   新地址: {}", address);
                
                // 检查是否包含IP地址信息
                for proto in address.iter() {
                    if let Protocol::Ip4(ip) = proto {
                        println!("   🎯 地址包含IP4: {}", ip);
                    } else if let Protocol::Ip6(ip) = proto {
                        println!("   🎯 地址包含IP6: {}", ip);
                    }
                }
            },
            _ => {
                // 其他事件静默处理
            }
        }
    }
}
